package com.ygp.dtp.common.utils;

import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @description: XML字符串与Map、List的互相转换
 * @motto: 代码源于生活，高于生活艺术
 * @author: zhouhengzhe
 * @date: 2022/8/9 14:48
 * @since 1.0
 **/
public class XmlUtil {

    /**
     * Map 转为 Xml string
     */
    public static String mapToXml(Map<String, Object> map) {
        StringBuffer buffer = new StringBuffer();
        buffer.append("<DataInfo>");
        buffer.append(convert(map));
        buffer.append("</DataInfo>");
        return buffer.toString();
    }

    @SuppressWarnings("unchecked")
    private static String convert(Map<String, Object> map) {
        StringBuffer buffer = new StringBuffer();
        for (String key : map.keySet()) {
            // 拼接xml开头标签
            buffer.append("<" + key + ">");
            //值为Map类型
            if (map.get(key) instanceof Map) {
                String element = convert((Map<String, Object>) map.get(key));
                buffer.append(element);
                //值为List类型
            } else if (map.get(key) instanceof List) {
                List<Map<String, Object>> list = (ArrayList<Map<String, Object>>) map.get(key);
                for (int i = 0; i < list.size(); i++) {
                    buffer.append("<entry>");
                    Map<String, Object> m = (HashMap<String, Object>) list.get(i);
                    String element = convert((Map<String, Object>) m);
                    buffer.append(element);
                    buffer.append("</entry>");
                }
            } else {
                buffer.append(map.get(key));
            }
            // 收尾标签
            buffer.append("</" + key + ">");
        }
        return buffer.toString();
    }

    /**
     * Xml string 转为 Map
     */
    @SuppressWarnings("unchecked")
    public static Map<Object, Object> xmlToMap(String str) {
        Map<Object, Object> result = new HashMap<>();
        try {
            Element root = DocumentHelper.parseText(str).getRootElement();
            // 获取所有子节点
            List<Element> elements = root.elements();
            for (Element element : elements) {
                result.put(element.getName(), element.getText());
            }
            return result;
        } catch (DocumentException e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * Xml string 转为 List
     */
    @SuppressWarnings("unchecked")
    public static List<Map<String, Object>> xmlToList(String str) {
        List<Map<String, Object>> result = new ArrayList<>();
        try {
            Element root = DocumentHelper.parseText(str).getRootElement();
            // 获取所有子节点
            List<Element> elements = root.elements();
            for (Element element : elements) {
                List<Element> childElements = element.elements();
                Map<String, Object> map = new HashMap<>();
                for (Element childElement : childElements) {
                    map.put(childElement.getName(), childElement.getText());
                }
                result.add(map);
            }
            return result;
        } catch (DocumentException e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * Xml string 转为 Map(其中包含List)
     */
    @SuppressWarnings("unchecked")
    public static Map<String, Object> xmlToMapList(String str) {
        Map<String, Object> result = new HashMap<>();
        try {
            Element root = DocumentHelper.parseText(str).getRootElement();
            // 获取所有子节点
            List<Element> elements = root.elements();
            for (Element element : elements) {
                //若子节点还包含子节点,则转为List集合,否则转为Map集合
                List<Element> childNodes = element.elements();
                if (childNodes != null && childNodes.size() > 0 && childNodes.get(0).elements().size() > 0) {
                    List<Map<String, Object>> reList = xmlToList(element.asXML());
                    result.put(element.getName(), reList);
                } else {
                    Map<Object, Object> map = xmlToMap(element.asXML());
                    result.put(element.getName(), map);
                }
            }
            return result;
        } catch (DocumentException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static void main(String[] args) throws Exception {
        Map<String, Object> headMap = new HashMap<>();
        headMap.put("creator", "API");
        headMap.put("token", "123456");
        List<Map<String, Object>> dataList = new ArrayList<>();
        Map<String, Object> dataMap = new HashMap<>();
        dataMap.put("xm", "张三");
        dataMap.put("birthdate", "1990-01-18 11:10:41");
        dataList.add(dataMap);
        dataMap = new HashMap<>();
        dataMap.put("xm", "李四");
        dataMap.put("birthdate", "1991-01-18 11:10:41");
        dataList.add(dataMap);
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("DataHead", headMap);
        paramMap.put("DataEntries", dataList);
        //Map转xml字符串
        String xmlStr = mapToXml(paramMap);
        System.out.println("Map转xml字符串:" + xmlStr);
        //xml字符串转Map
        Map<String, Object> map = xmlToMapList(xmlStr);
        System.out.println("xml字符串转Map:" + map);
    }
}
